﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Security.Permissions;

namespace Model.Crafters
{
    [Serializable]
    public abstract class Crafter : INotifyPropertyChanged
    {
        /*
         *craftmanship, flair, enchanting, spellcrafting, inventing
         */

        private String _Name;
        private String _Race;
        private String _Profession; //blacksmith, mage, etc
        private int _Level;
        private int _Intellect;
        private int _XP;
        private int _AvailableSkillPoints;

        private List<Skill> _Skills; //craftmanship, flair, enchanting, spellcrafting, inventing etc.

        public Crafter()
        {
            _Skills = new List<Skill>();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        public String Name
        {
            get { return _Name; }
            set
            {
                _Name = value;
                NotifyPropertyChanged("Name");
            }
        }

        public String Race
        {
            get { return _Race; }
            set
            {
                _Race = value;
                NotifyPropertyChanged("Race");
            }
        }

        public String Profession
        {
            get { return _Profession; }
            set
            {
                _Profession = value;
                NotifyPropertyChanged("Profession");
            }
        }

        public int Level
        {
            get { return _Level; }
            set
            {
                _Level = value;                                    
                NotifyPropertyChanged("Level");
            }
        }

        public int Intellect
        {
            get { return _Intellect; }
            set
            {
                _Intellect = value;
                NotifyPropertyChanged("Intellect");
            }
        }

        public int XPToLvl
        {
            get { return (int)(10 * Math.Exp(Level - 1) + 1000); }
        }

        public int XP
        {
            get { return _XP; }
            set
            {
                _XP = value;
                while (_XP > XPToLvl)
                {
                    _XP -= XPToLvl;
                    LevelUp();
                }

                NotifyPropertyChanged("XP");
            }
        }

        public List<Skill> Skills
        {
            get { return _Skills; }
            set
            {
                _Skills = value;
                NotifyPropertyChanged("Skills");
            }
        }

        public int AvailableSkillPoints
        {
            get { return _AvailableSkillPoints; }
            set
            {
                _AvailableSkillPoints = value;
                NotifyPropertyChanged("AvailableSkillPoints");
            }
        }
        
        public void LevelUp()
        {
            //int xp = XP - XPToLvl;
            Level++;
            AvailableSkillPoints += Intellect / 2;

           // return xp; //xp in new level
        }

        public override String ToString()
        {
            String str =
                   "Name: " + Name + "\n" +
                   "Race: " + Race + "\n" +
                   "Profession: " + Profession + "\n" +
                   "Level: " + Level + "\n" +
                   "Intellect: " + Intellect + "\n" +
                   "XP: " + XP + "\n" +
                   "Available skillpoint: " + AvailableSkillPoints + "\n" +
                   "XP to next level: " + XPToLvl + "\n";
            foreach(Skill skill in Skills)
                str += skill + "\n";

            return str;
        }
    }
}
